#ifndef NSI_SPIKE_UTIL_SIGNAL_CHAIN_H
#define NSI_SPIKE_UTIL_SIGNAL_CHAIN_H

#include <list>
#include "singleton.h"
#include "signal_base.h"
#include "default_signal.h"

namespace nsi {
namespace spike {

// Forward declaration of signal
template <int Signal>
class signal;

template <int Signal>
class signal_chain
{
public:
  
  // Signal chain list
  typedef std::list<signal_base*> list_type;

  // Signal value
  enum value_type
  {
    signal_value = Signal
  };

  // Destructor
  ~signal_chain()
  {
    // Delete our list of signals 
    for (list_type::iterator iter = list_.begin(); iter != list_.end(); ++iter)
      delete *iter;
  }

  // Accessors
  // Return the raw list
  const list_type& list() const
  {
    return list_;
  }

  // Singleton instance
  static signal_chain& instance()
  {
    return singleton<signal_chain>::instance();
  }

private:
  // Default constructor
  explicit signal_chain()
  {
    // Get the default signal
    default_signal* signal = new default_signal(signal_value);
    signal->create();

    list_.push_front(signal);
  }
  
  // No copy constructor
  signal_chain(const signal_chain&);
  // No assignment operator
  signal_chain& operator=(const signal_chain&);
  
  // Give signal friend access
  friend class signal<signal_value>;
  // Give singleton friend access
  friend class singleton<signal_chain>;

  // Signal chain
  list_type list_;
};

} // namespace spike
} // namespace nsi

#endif // !NSI_SPIKE_UTIL_SIGNAL_CHAIN_H
